#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef WIN32
#include "getopt_win32.h"
#else
#include <unistd.h>
#endif

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

#include "topdbs.hpp"

#define TOPDBS_CONF  "topdbs.ini"

typedef struct tagDbsParams
{
	char dbsType[20];
	char dbsUser[20];
	char dbsPass[40];
	char dbsConn[256];
	char dbsEncode[20];
	char dbsEncrypt[10];
    char dbsCommand[512];
	char dbsFile[40];
	char dbsGroup[40];
}dbsParams_t;

void exit_system(int code)
{
#ifdef WIN32	
	system("pause");
#endif		
	exit(code);	
}

void dbsUsage(int argc,char* argv[])
{
	if (argc < 3)
	{
		printf("***************************************************************************\n");
		printf("* Usage: \n");
		printf("* %s -t dbsType -u user -p pass -c dbConnStr \n",argv[0]);
		printf("* %s -f dbsfile -g dbsgname \n",argv[0]);
		printf("***************************************************************************\n");
		exit_system(0);
	}
}

int dbsGetOption(int argc,char* argv[],dbsParams_t* dbsParams)
{
	int ret = 0;
	char ch;
	while ( (ch = getopt(argc, argv, "t:u:p:c:e:m:E:f:g:")) != -1)
	{
		ret = 0;
		switch (ch)
		{
			case 't':
				strcpy(dbsParams->dbsType, optarg);
				break;
			case 'u':
				strcpy(dbsParams->dbsUser, optarg);
				break;
			case 'p':
				strcpy(dbsParams->dbsPass, optarg);
				break;
			case 'c':
				strcpy(dbsParams->dbsConn, optarg);
				break;
			case 'e':
				strcpy(dbsParams->dbsEncode, optarg);
				break;
			case 'm':
				strcpy(dbsParams->dbsEncrypt, optarg);
				break;
			case 'E':
				strcpy(dbsParams->dbsCommand, optarg);
				break;
			case 'f':
				strcpy(dbsParams->dbsFile, optarg);
				break;	   				
			case 'g':
				strcpy(dbsParams->dbsGroup, optarg);
				break;	          		
			default :
				printf("ERROR falgs!\n");
				ret=-1;
				break;
		}
		if (ret < 0)
		{
			return -1;
		}
	}
	return 0;
}

int dbsConnect(dbsParams_t& dbsInputParams)
{
	if(strlen(dbsInputParams.dbsGroup) > 0)
	{
		char sTopdbs_ini[256] = {0};
		sprintf(sTopdbs_ini,"%s%cetc%c%s",
			getenv(USERHOME),PATH_DELIMITER,PATH_DELIMITER,
				strlen(dbsInputParams.dbsFile) == 0 ? TOPDBS_CONF : dbsInputParams.dbsFile);
		if( SQLConnection::InitEnv(sTopdbs_ini,dbsInputParams.dbsGroup) != 0)
		{
			printf("InitEnv failed!!!\n");
			return -1;
		}
		std::cout << "dbConnection:[" << sTopdbs_ini << "]["<< dbsInputParams.dbsGroup << "]" << endl;
	}
	else
	{
		if(strlen(dbsInputParams.dbsType) == 0)
		{
			printf("The dbsType is NULL\n");
			return -1;
		}
		eDBSClient_t dbsClient = topdbs_client_type(dbsInputParams.dbsType);
		if(dbsClient == topdbs_unkown )
		{
			printf("The dbsType %s is invalid.\n",dbsInputParams.dbsType);
			return -1;
		}    

		if(strlen(dbsInputParams.dbsUser) == 0 && dbsClient != topdbs_sqlite )
		{
			printf("The databaes user is NULL\n");
			return -1;
		}

		if(strlen(dbsInputParams.dbsPass) == 0 && dbsClient != topdbs_sqlite )
		{
			printf("The databaes pass is NULL\n");
			return -1;
		}   

		if(strlen(dbsInputParams.dbsConn) == 0)
		{
			printf("The databaes connStr is NULL\n");
			return -1;
		} 

		bool bEncrypt = false;
		if(strlen(dbsInputParams.dbsEncrypt) > 0 && strcmp(dbsInputParams.dbsEncrypt,"yes") == 0)
		{
			bEncrypt = true;
		}
		
		if( SQLConnection::InitEnv(
			dbsClient,
			dbsInputParams.dbsConn,
			dbsInputParams.dbsUser,
			dbsInputParams.dbsPass,
			dbsInputParams.dbsEncode,
			bEncrypt) != 0)
		{
			printf("InitEnv failed!!!\n");
			return -1;
		}

	}		
    cout << "The database connection succed." << endl;
    return 0;
}

int dbsDisconnect()
{
    return SQLConnection::UnIntEnv();
}

int main(int argc,char* argv[])
{
	int iRet = 0;
	dbsParams_t dbsInputParams;
	memset(&dbsInputParams,0x00,sizeof(dbsInputParams));
	dbsUsage(argc,argv);
	
	if( dbsGetOption(argc,argv,&dbsInputParams) != 0 )
	{
		dbsUsage(argc,argv);
		return -1;
	}	
    if( dbsConnect(dbsInputParams) != 0)
    {
		std::cout << "dbsconnection check unsucced." << endl;
        return -1;
    }
	std::cout << "dbsconnection check succed." << endl;
	
    dbsDisconnect();
	return iRet;
}